﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Drawing;
using System.IO;
using System.Drawing.Imaging;
using AnnotateMe.Logic;
using AnnotateMe.Interfaces;

namespace AnnotateMe.Web
{
    public partial class AnnotateMe : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            string query = Request.QueryString["query"];

            using (var image = new Bitmap(2000, 200))
            {
                const string Error = "I'm afraid I can't do that.";

                var graphics = Graphics.FromImage(image);
                graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;

                var colorProvider = new RandomColorProvider();
                var queryParser = new CaretDelimitedQueryParser();
                var annotator = new SimpleAnnotator();
                var layoutService = new SimpleLayoutService((startPoint, endPoint) => new LineSegmentConnector(startPoint, endPoint, (sPoint, ePoint) => graphics.DrawLine(Pens.Black, sPoint.ToPointF(), ePoint.ToPointF())));

                Shape shape;
                try
                {
                    var tuples = queryParser.Parse(query);
                    var inputs = tuples.Select(t => new Tuple<string, string, Color?>(t.Item1, t.Item2, (t.Item2 == string.Empty) ? (Color?)null : colorProvider.GetNextColor()));
                    shape = layoutService.Arrange(annotator.CreateBlocks(inputs, new Font("Consolas", 16), new Font("Verdana", 8), graphics).ToList());
                }
                catch
                {
                    shape = layoutService.Arrange(annotator.CreateBlocks(new[] { new Tuple<string, string, Color?>(Error, null, null) }, new Font("Consolas", 16), new Font("Verdana", 8), graphics).ToList());
                }

                var boundingRectangle = shape.GetContainingRectangle();

                const int Margin = 20;
                shape = shape.MoveBy(Margin - boundingRectangle.OriginPoint.X, Margin - boundingRectangle.OriginPoint.Y);

                shape.Draw();

                using (var clippedImage = new Bitmap((int)boundingRectangle.Size.Width + 2 * Margin, (int)boundingRectangle.Size.Height + 2 * Margin))
                {
                    var clippedGraphics = Graphics.FromImage(clippedImage);
                    clippedGraphics.DrawImage(image, 0, 0);

                    using (var ms = new MemoryStream())
                    {
                        clippedImage.Save(ms, ImageFormat.Png);
                        Response.ContentType = "image/png";
                        Response.OutputStream.Write(ms.ToArray(), 0, (int)ms.Length);
                    }
                }
            }
        }
    }
}